<template>
  <div class="IndexAdd">
    <vxe-grid
      ref="xGrid"
      border
      resizable
      round
      show-footer
      class="my-grid66"
      :columns="tableColumn"
      :data="tableData"
      :header-cell-style="headerCellStyle"
      :cell-style="cellStyle"
      :footer-method="footerMethod"
    >
      <!-- 年份-->
      <template #input_year="{ row }">
        <div>
          <el-date-picker
            v-model="row.year"
            style="width:100%;"
            type="year"
            placeholder="选择年份"
            value-format="yyyy"
          />
        </div>
      </template>

      <!-- 乡镇 -->
      <template #input_enterpriseName="{ row }">
        <div>
          <el-select
            v-model="row[selectOpintionConfig.enterprise.itemKey]"
            placeholder="请选择"
            @change="(value) => selectChange(value, selectOpintionConfig.enterprise, row)"
            @focus="getSelectOpintion('enterprise')"
          >
            <el-option
              v-for="(item, index) in selectOpintionConfig.enterprise.opintion"
              :key="index"
              :label="item[selectOpintionConfig.enterprise.showLabel]"
              :value="item[selectOpintionConfig.enterprise.resKey]"
              @click.native="findConfigOpintionIndex(selectOpintionConfig.enterprise, index)"
            />
          </el-select>
        </div>
      </template>

      <!-- 归口 -->
      <template #input_divisionName="{ row }">
        <div>
          <el-select
            v-model="row[selectOpintionConfig.division.itemKey]"
            disabled
            placeholder="请选择"
            @change="(value) => selectChange(value, selectOpintionConfig.division, row)"
            @focus="getSelectOpintion('division')"
          >
            <el-option
              v-for="(item, index) in selectOpintionConfig.division.opintion"
              :key="index"
              :label="item[selectOpintionConfig.division.showLabel]"
              :value="item[selectOpintionConfig.division.resKey]"
              @click.native="findConfigOpintionIndex(selectOpintionConfig.division, index)"
            />
          </el-select>
        </div>
      </template>

      <!-- 项目名称 -->
      <template #input_programName="{ row }">
        <div>
          <el-autocomplete
            v-model="row.programName"
            :fetch-suggestions="(query, cb) => querySearchAsync(query, cb, row)"
            placeholder="请输入内容"
            @blur="({target: {value}}) => inputCompleteBlur(value, row)"
            @select="(value) => handleSelect(value, row)"
          />
        </div>
      </template>

      <!-- 资金来源 -->
      <template #input_resourceName="{ row }">
        <div>
          <el-select
            v-model="row[selectOpintionConfig.resource.itemKey]"
            placeholder="请选择"
            @change="(value) => selectChange(value, selectOpintionConfig.resource, row)"
            @focus="getSelectOpintion('resource')"
          >
            <el-option
              v-for="(item, index) in selectOpintionConfig.resource.opintion"
              :key="index"
              :label="item[selectOpintionConfig.resource.showLabel]"
              :value="item[selectOpintionConfig.resource.resKey]"
              @click.native="findConfigOpintionIndex(selectOpintionConfig.resource, index)"
            />
          </el-select>
        </div>
      </template>

      <!-- 指标类型 -->
      <template #input_budgetcategoryName="{ row }">
        <div>
          <el-select
            v-model="row[selectOpintionConfig.budget.itemKey]"
            placeholder="请选择"
            @change="(value) => selectChange(value, selectOpintionConfig.budget, row)"
            @focus="getSelectOpintion('budget')"
          >
            <el-option
              v-for="(item, index) in selectOpintionConfig.budget.opintion"
              :key="index"
              :label="item[selectOpintionConfig.budget.showLabel]"
              :value="item[selectOpintionConfig.budget.resKey]"
              @click.native="findConfigOpintionIndex(selectOpintionConfig.budget, index)"
            />
          </el-select>
        </div>
      </template>

      <!-- 功能科目-名称 -->
      <template #input_function="scoped">
        <div>
          <!-- <el-input v-model="row.functionName" placeholder="请输入内容" /> -->
          <Select-Tree
            :item="scoped.row"
            :choose-year="chooseYear"
            :common-index="scoped.rowIndex"
            :label="selectTreeOpintionConfig.function.itemKey"
            :show-label="selectTreeOpintionConfig.function.showLabel"
            :item-url="selectTreeOpintionConfig.function.url"
            :placeholder="'请选择'"
            :common-values="scoped.row[selectTreeOpintionConfig.function.itemKey]"
            @changeData="(data) => changeSelectTreeData(data, scoped.row, selectTreeOpintionConfig.function)"
          />
        </div>
      </template>

      <!-- 金额 -->
      <template #input_money="{ row }">
        <div>
          <el-input
            v-model="row.money"
            type="number"
            placeholder="请输入内容"
            :min="0"
            @input="(v) => numberReg(v, row)"
            @change="upDataTable"
          />
        </div>
      </template>

      <!-- 文件依据-文号 -->
      <template #input_fileNo="{ row }">
        <div>
          <el-input v-model="row.fileNo" placeholder="请输入内容" />
        </div>
      </template>

      <!-- 文件依据-发文日期-->
      <template #input_postFileDate="{ row }">
        <div>
          <el-date-picker
            v-model="row.postFileDate"
            style="width:100%;"
            type="date"
            placeholder="选择日期"
            value-format="yyyy-MM-dd"
          />
        </div>
      </template>

      <!-- 文件依据-原文号 -->
      <template #input_originalFileNo="{ row }">
        <div>
          <el-input v-model="row.originalFileNo" placeholder="请输入内容" />
        </div>
      </template>

      <!-- 文件依据-原发文日期-->
      <template #input_originalFileDate="{ row }">
        <div>
          <el-date-picker
            v-model="row.originalFileDate"
            style="width:100%;"
            type="date"
            placeholder="选择日期"
            value-format="yyyy-MM-dd"
          />
        </div>
      </template>

      <!-- 入账日期 -->
      <template #input_accountDate="{ row }">
        <div>
          <el-date-picker
            v-model="row.accountDate"
            style="width:100%;"
            type="date"
            value-format="yyyy-MM-dd"
            placeholder="选择日期"
          />

        </div>
      </template>

      <!-- 备注 -->
      <template #input_remark="{ row }">
        <div>
          <el-input v-model="row.remark" placeholder="请输入内容" />
        </div>
      </template>

      <!-- 文件 -->
      <template #input_file="{ row }">
        <div class="indexAdd-file">
          <div>
            <el-upload
              class="upload-demo"
              :file-list="row.fileList"
              :auto-upload="false"
              :on-change="(file, fileList) => takeFile(file, row)"
              action="https://jsonplaceholder.typicode.com/posts/"
              :show-file-list="false"
              multiple
            >
              <el-button slot="trigger" size="small" type="text"><i class="el-icon-upload2" />点击上传</el-button>
            </el-upload>

            <el-popover
              v-show="row.fileList.length"
              placement="left"
              trigger="click"
            >
              <div class="indexAdd-fileview">
                <template v-if="row.fileList.length">
                  <div v-for="(file, index) in row.fileList" :key="index">
                    <div class="indexAdd-file-view">
                      <label style="margin-right: 10px;">{{ file.name }}</label>
                      <el-button size="small" type="text" @click="removeFile(row.fileList, index)"><span style="color:#F56C6C;">删除</span></el-button>
                    </div>
                  </div>
                </template>
                <div v-else>
                  暂无文件
                </div>
              </div>
              <el-button
                slot="reference"
                size="small"
                type="text"
              ><i class="el-icon-view" />
                查看文件
              </el-button>
            </el-popover>

          </div>
        </div>
      </template>

      <template #bottom>
        <div class="IndexAdd-submit">
          <span class="alert-message-content">
            <el-button size="small" type="primary" @click="formSubmit">提交</el-button>
          </span>
        </div>
      </template>
    </vxe-grid>
  </div>
</template>

<script type="text/ecmascript-6">
import _ from 'lodash';
import { getCommonDataSource } from '@/api/reportCenter';
import { inBudgetAdd } from '@/api/indexInput';
import { uploadMulti } from '@/api/file';
import { AmountSlite } from '@/utils/utils';
import SelectTree from '@/views/indexInput/components/SelectTree.vue';

export default {
  components: {
    SelectTree
  },
  inject: ['connectStore'],
  data() {
    const minColunmsWidth = '157px';

    return {
      chooseYear: localStorage.getItem('chooseYear'),
      programOption: [],
      selectOpintionConfig: {
        resource: {
          url: 'jc/getResource',
          itemKey: 'resourceName',
          resKey: 'resourceCateName',
          showLabel: 'resourceCateText',
          bindKey: ['resourceGuid', 'resourceCode'],
          bindKeyRes: ['resourceCateGuid', 'resourceCateCode'],
          opintion: [],
          selOpintionIndex: -1
        },
        budget: {
          url: 'jc/getBudgetCategory',
          itemKey: 'budgetcategoryName',
          resKey: 'budgetCategoryName',
          showLabel: 'budgetcategoryName',
          bindKey: ['budgetcategoryGuid', 'budgetcategoryName', 'budgetcategoryCode'],
          bindKeyRes: ['budgetCategoryGuid', 'budgetCategoryName', 'budgetCategoryCode'],
          opintion: [],
          selOpintionIndex: -1
        },
        division: {
          url: 'jc/getDivisionByEnter',
          itemKey: 'divisionName',
          resKey: 'divisionName',
          showLabel: 'divisionName',
          bindKey: ['divisionGuid'],
          bindKeyRes: ['divisionGuid'],
          opintion: [],
          selOpintionIndex: -1
        },
        enterprise: {
          url: 'capitalUser/showEnterprise',
          itemKey: 'enterpriseName',
          resKey: 'name',
          showLabel: 'name',
          bindKey: ['enterpriseCode', 'enterpriseGuid', 'enterpriseName'],
          bindKeyRes: ['enterpriseCode', 'enterpriseGuid', 'name'],
          opintion: [],
          selOpintionIndex: -1,
          requestData: { // 单独设置请求参数
            userId: localStorage.getItem('xcUserId'),
            requestKey: 'enterprise' // 标识是乡镇（自用）
          }
        }
      },
      selectTreeOpintionConfig: {
        function: {
          url: 'jc/getFunctionSection',
          itemKey: 'functionName',
          resKey: 'functionSectionName',
          showLabel: 'functionSectionText',
          bindKey: ['functionCode', 'functionGuid', 'functionName'],
          bindKeyRes: ['functionSectionCode', 'functionSectionGuid', 'functionSectionName']
        }
      },
      loadingConfig: {
        lock: true,
        text: '正在上传新指标',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      },
      tableData: [
        {
          rn: '',
          year: localStorage.getItem('chooseYear'),
          enterpriseName: '',
          divisionName: '',
          programName: '',
          programCode: '',
          resourceName: '',
          budgetcategoryName: '',
          functionCode: '',
          functionName: '',
          money: '',
          fileNo: '',
          postFileDate: '',
          originalFileNo: '',
          originalFileDate: '',
          accountDate: '',
          remark: '',
          annex: '', // 上传文件时候录入文件名进来，多文件之间逗号
          fileList: []
        }
      ],
      tableColumn: [
        { field: 'operating', title: '操作', minWidth: minColunmsWidth, fixed: 'left', treeNode: true, slots: {
          default: (scoped) => {
            const { row, _rowIndex } = scoped;
            if (_rowIndex === 0) {
              return [
                <div class='indexinput-table-cell-operating'>
                  <el-button onClick={() => this.copyRow(row)} type='text'>复制</el-button>
                </div>
              ];
            }
            return [
              <div class='indexinput-table-cell-operating'>
                <el-button onClick={() => this.copyRow(row)} type='text'>复制</el-button>

                <el-button onClick={() => this.delectRow(scoped)} type='text'><span style='color:#FF4D4F;'>删除</span></el-button>
              </div>
            ];
          }
        }},
        { field: 'year', minWidth: minColunmsWidth, title: '年份', slots: { default: 'input_year' }},
        { field: 'enterpriseName', minWidth: minColunmsWidth, title: '乡镇', slots: { default: 'input_enterpriseName' }, cqcName: 'cqc' },
        { field: 'divisionName', minWidth: minColunmsWidth, title: '归口', slots: { default: 'input_divisionName' }},
        { field: 'programName', minWidth: minColunmsWidth, title: '项目名称', slots: { default: 'input_programName' }},
        { field: 'resourceName', minWidth: minColunmsWidth, title: '资金来源', slots: { default: 'input_resourceName' }},
        { field: 'budgetcategoryName', minWidth: minColunmsWidth, title: '指标类型', slots: { default: 'input_budgetcategoryName' }},
        { field: 'functionName', minWidth: minColunmsWidth, title: '功能科目', slots: { default: 'input_function' }},
        { field: 'money', minWidth: minColunmsWidth, title: '金额', slots: { default: 'input_money' }},
        {
          title: '文件依据',
          children: [
            { field: 'fileNo', minWidth: minColunmsWidth, title: '文号', slots: { default: 'input_fileNo' }},
            { field: 'postFileDate', minWidth: minColunmsWidth, title: '发文日期', slots: { default: 'input_postFileDate' }}
          ]
        },
        {
          title: '原文件依据',
          children: [
            { field: 'originalFileNo', minWidth: minColunmsWidth, title: '原文号', slots: { default: 'input_originalFileNo' }},
            { field: 'originalFileDate', minWidth: minColunmsWidth, title: '原发文日期', slots: { default: 'input_originalFileDate' }}
          ]
        },

        { field: 'accountDate', minWidth: minColunmsWidth, title: '入账日期', slots: { default: 'input_accountDate' }},
        { field: 'remark', minWidth: minColunmsWidth, title: '备注', slots: { default: 'input_remark' }},
        { field: 'fileList', title: '附件', minWidth: minColunmsWidth, fixed: 'right', slots: { default: 'input_file' }}
      ]
    };
  },

  methods: {
    inputCompleteBlur(programName, row) {
      if (programName) {
        getCommonDataSource({ programName }, 'budget/in/getProgram').then(res => {
          if (res.success) {
            row.programCode = res.data.programCode;
          }
        });
      }
    },
    // 项目名称选中
    handleSelect(v, row) {
      row.programCode = v.programCode;
    },
    // 项目名称输入
    querySearchAsync(query, cb, row) {
      row.programCode = '';
      if (query) {
        getCommonDataSource({
          programName: query
        }, 'budget/in/getProgramList').then(res => {
          if (res.success) {
            res.data.forEach(item => {
              item.value = item.programName;
            });
            this.programOption = res.data;
            cb(res.data);
          } else {
            cb([]);
            this.programOption = [];
          }
        });
      } else {
        this.programOption = [];
        cb([]);
      }
    },

    changeSelectTreeData({ data }, row, { bindKey, bindKeyRes }) {
      bindKey.forEach((bkey, i) => {
        row[bkey] = data[bindKeyRes[i]];
      });
      this.upDataTable();
    },
    selectChange(value, config, row) {
      setTimeout(() => {
        const { opintion, selOpintionIndex, bindKey, bindKeyRes } = config;
        const selNow = opintion[selOpintionIndex];
        bindKey.forEach((item, index) => {
          row[item] = selNow[bindKeyRes[index]];
        });

        this.otherConfig(config, row, selNow);

        this.upDataTable();
      });
    },

    // 是否还有其他操作
    otherConfig(config, row, selNow) {
      const { requestData } = config;
      // 下拉选择乡镇  联动归口
      if (requestData && requestData.requestKey === 'enterprise') {
        this.selectOpintionRequest('capital/getDivisionByEnter', {
          requestData: {
            year: this.chooseYear,
            isbnCode: selNow.enterpriseCode
          }
        }).then(list => {
          if (Array.isArray(list) && list.length) {
            const bindKey = ['divisionGuid', 'divisionName'];
            const bindKeyRes = ['divisionGuid', 'divisionName'];
            this.rowBind(row, bindKey, bindKeyRes, list[0]);
          }
        });
      }
    },

    rowBind(row, bindKey, bindKeyRes, selNow) {
      bindKey.forEach((key, index) => {
        row[key] = selNow[bindKeyRes[index]];
      });
    },

    findConfigOpintionIndex(config, index) {
      config.selOpintionIndex = index;
    },

    getSelectOpintion(configKey) {
      const config = this.selectOpintionConfig[configKey];
      if (!config.opintion.length) {
        this.selectOpintionRequest(config.url, config).then(list => {
          config.opintion = list;
        });
      }
    },

    selectOpintionRequest(url, { requestData: params }) {
      const requestData = {
        year: localStorage.getItem('chooseYear'),
        enterGuid: JSON.parse(localStorage.getItem('enterprise_jc'))[0].ENTERPRISE_GUID,
        userId: localStorage.getItem('xcUserId')
      };
      return getCommonDataSource(params || requestData, url).then(res => {
        if (res.success) {
          // 单独对乡镇数据进行过滤 （目前就乡镇特殊处理）
          if (params) {
            if (params.requestKey === 'enterprise') {
              res.data = res.data.filter(item => item.isCheck === 1);
              res.data.forEach(item => {
                item.enterpriseCode = item.label.split(' ')[0];
              });
            }
          }
          return Promise.resolve(res.data);
        }
      });
    },

    numberReg(v, row) {
      if (v < 0) {
        row.money = 0;
        this.$message.warning('金额不能是负数');
      }
    },

    takeFile(file, row) {
      if (file.status === 'ready') {
        row.fileList.push(file);
        this.upDataTable();
      }
    },

    fileRelated(row, type) {
      console.log(row, type);
    },

    removeFile(fileList, index) {
      this.$message.success('删除文件成功');
      fileList.splice(index, 1);
    },

    upDataTable() {
      this.$refs.xGrid.refreshColumn();
    },

    copyRow(row) {
      this.tableData.push(_.cloneDeep(row));
    },

    delectRow({ rowIndex }) {
      this.tableData.splice(rowIndex, 1);
    },

    // 校验提交数据
    formReg(data) {
      let flag = true;
      let fileSameErr = false;
      let sameRowErr = false;
      let sameRowErrIndex = [];
      // 非空字段
      const notNull = {
        year: {
          label: '年份'
        },
        enterpriseName: {
          label: '乡镇'
        },
        divisionName: {
          label: '归口'
        },
        programName: {
          label: '项目名称'
        },
        resourceName: {
          label: '资金来源'
        },
        budgetcategoryName: {
          label: '指标类型'
        },
        money: {
          label: '金额'
        },
        fileNo: {
          label: '文号'
        },
        postFileDate: {
          label: '发文日期'
        },
        accountDate: {
          label: '入账日期'
        }
      };
      const notNullArr = Object.keys(notNull);
      let warnKey = '';
      for (let i = 0; i < data.length; i++) {
        if (!flag || fileSameErr) {
          break;
        }
        const fileNameArr = [];
        data[i].fileList.forEach(file => {
          if (fileNameArr.includes(file.name)) {
            fileSameErr = true;
          }
          fileNameArr.push(file.name);
        });
        const rowKeys = Object.keys(data[i]);
        for (let j = 0; j < rowKeys.length; j++) {
          const keyItem = rowKeys[j];
          if (notNullArr.includes(keyItem) && data[i][keyItem] === '') {
            flag = false;
            warnKey = keyItem;
            break;
          }
        }
      }

      for (let i = 0; i < data.length; i++) {
        const itemCurr = data[i];
        if (sameRowErr) {
          break;
        }
        for (let j = i + 1; j < data.length; j++) {
          const itemNext = data[j];
          const compare = JSON.stringify(itemCurr) === JSON.stringify(itemNext);
          if (compare) {
            sameRowErr = true;
            sameRowErrIndex = [i, j];
            break;
          }
        }
      }
      if (sameRowErr) {
        this.$message.warning('每条记录之间不能完全一致,' + `检测到第${sameRowErrIndex[0] + 1}行、第${sameRowErrIndex[1] + 1}行 一致`);
        return false;
      }
      if (fileSameErr) {
        this.$message.warning('单条记录上传的文件名字不能重复');
        return false;
      }
      if (warnKey) {
        this.$message.warning(notNull[warnKey].label + '不能为空');
        return false;
      }

      return flag;
    },

    // 提交
    formSubmit() {
      const fileMark = [];
      const fileCollect = [];
      const fileGuid = [];

      const formSubmitFlag = this.formReg(this.tableData);
      if (!formSubmitFlag) {
        return;
      }

      const loading = this.$loading(this.loadingConfig);
      /* setTimeout(() => {
        loading.close();
        this.loadingConfig.text = '正在上传附件';
        const loading2 = this.$loading(this.loadingConfig);
        setTimeout(() => {
          loading2.close();
          this.loadingConfig.text = '正在上传新指标';
        }, 2000);
      }, 2000); */

      this.tableData.forEach((item, i) => {
        // 收集要上传文件的名字
        item.annex = item.fileList.reduce((prev, curr, index) => {
          prev = prev + curr.name;
          if (!(index === item.fileList.length - 1)) {
            prev = prev + ',';
          }
          return prev;
        }, '');

        // 标记每个row的file数量  收集file
        if (item.fileList.length) {
          fileMark.push({
            number: item.fileList.length,
            index: i
          });

          item.fileList.map(file => {
            fileCollect.push(file.raw);
          });
        }
      });

      const upParams = {
        creator: localStorage.getItem('xcUserId'),
        list: this.tableData
      };

      inBudgetAdd(upParams).then(res => {
        if (res.success) {
          this.$message.success(res.message);
          loading.close();

          // 录入成功返回的guid(多文件上传用到)
          const mockSuccess = res.data;
          fileMark.map(item => {
            while (item.number) {
              fileGuid.push(this.connectStore.value.fileUpGuidAddition + mockSuccess[item.index]);
              item.number--;
            }
          });

          // todo 上传文件
          const upFileRequestData = new FormData();
          for (let index = 0; index < fileCollect.length; index++) {
            upFileRequestData.append('files', fileCollect[index]);
          }
          upFileRequestData.append('guid', fileGuid.join(','));
          if (fileGuid.length) {
            this.loadingConfig.text = '正在上传附件';
            const loading2 = this.$loading(this.loadingConfig);
            uploadMulti(upFileRequestData).then(res => {
              if (res.success) {
                this.$message.success(res.message);
                loading2.close();
                this.loadingConfig.text = '正在上传新指标';
                setTimeout(() => {
                  this.$emit('successBack');
                }, 500);
              }
            });
          } else {
            this.loadingConfig.text = '正在上传新指标';
            setTimeout(() => {
              this.$emit('successBack');
            }, 500);
          }
        }
      });
    },

    headerCellStyle() {
      return {
        'background-color': '#1890FF',
        'color': '#fff'
      };
    },

    cellStyle({ column }) {
      const style = {};
      const bgCell = ['operating', 'fileList'];
      if (bgCell.includes(column.property)) {
        style['background-color'] = '#E6F7FF';
      }
      return style;
    },

    footerMethod({ columns, data }) {
      const [content, sumArr] = [[], []];
      content[0] = sumArr;
      sumArr.length = columns.length;
      const money = data.reduce((prev, curr) => {
        prev = _.add(prev, curr.money * 1);
        return prev;
      }, 0);

      _.fill(sumArr, '').splice(7, 1, AmountSlite(money));
      sumArr.unshift('合计');
      return content;
    }
  }
};
</script>

<style lang="scss" scoped>
.IndexAdd {
  padding: 10px;
   .indexAdd-file {
     > div {
       display: flex;
       align-items: center;
       justify-content: space-between;
     }
    }

  /deep/ * {
    .IndexAdd-submit {
      position: relative;
      top: 30px;
      text-align: right;
    }
  }
}

/deep/ .vxe-table {
   .vxe-cell {
     text-align: center;
   }
}

.indexAdd-fileview {
  > div {
    width: 100%;
    > div {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
  }
}
</style>
